package com.gan.simple_init.controller;

import com.gan.simple_init.annotation.OperLog;
import com.gan.simple_init.common.base.ResponseResult;
import com.gan.simple_init.common.base.RestResultGenerator;
import com.gan.simple_init.common.constant.UserConstant;
import com.gan.simple_init.common.enums.BusinessType;
import com.gan.simple_init.common.exception.BusinessException;
import com.gan.simple_init.manager.RedisLimiterManager;
import com.gan.simple_init.util.UserCacheUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 用于测试:权限、限流、日志记录、线程池
 * @author gbw
 * @date 2023/8/8
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @Resource
    RedisLimiterManager redisLimiterManager;

    @Resource
    ThreadPoolExecutor threadPoolExecutor;

    @OperLog(title = "普通hello接口", businessType = BusinessType.OTHER)
    @ApiOperation("无权限测试接口-hello")
    @GetMapping("/hello")
    public String hello(){
        // 限流测试,使用业务前缀去区分开不同的限流器
        redisLimiterManager.doRateLimit("common_user_hello:" + UserCacheUtil.getUserCache().getId());
        return "hello user~";
    }

    @PreAuthorize(UserConstant.PRE_ROLE_NAME_ADMIN)
    @ApiOperation("有权限测试接口-hello")
    @GetMapping("/perm/hello")
    public String permHello(){
        return "hello admin~";
    }

    /**
     * 执行任务
     * @param name
     */
    @GetMapping("/threadPool/add")
    @ApiOperation("新建任务")
    public void add(String name){

        try {
            CompletableFuture.runAsync(() -> {
                System.out.println("任务" + name + "执行中:" + "  执行线程:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            },threadPoolExecutor);
        } catch (Exception e) {
            throw new BusinessException("已达到最大线程数，且任务队列已满!");
        }
    }


    /**
     * 查看线程情况
     */
    @GetMapping("/threadPool/get")
    @ApiOperation("查看线程情况")
    public ResponseResult<?> get(){
        HashMap<String, Object> res = new HashMap<>();
        int size = threadPoolExecutor.getQueue().size();
        res.put("队列长度/任务个数",size);
        long taskCount = threadPoolExecutor.getTaskCount();
        res.put("任务数量",taskCount);
        long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
        res.put("已完成任务数量",completedTaskCount);
        long activeCount = threadPoolExecutor.getActiveCount();
        res.put("正在工作的线程数",activeCount);
        return RestResultGenerator.success(res);
    }
}
